#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

// 题目（1）的编码函数：将比特转换为颜色
Scalar encodeBinary(int msg) {
    return (msg == 1) ? Scalar(255, 255, 255) : Scalar(0, 0, 0); // 白色代表1，黑色代表0
}

// 题目（1）的解码函数：将颜色转换为比特
int decodeBinary(Scalar color) {
    return (color[0] > 127) ? 1 : 0; // 判断颜色是否为白色
}

// 题目（2）的编码函数：将八进制位转换为颜色
Scalar encodeOctal(int msg) {
    switch (msg) {
        case 0: return Scalar(0, 0, 0);       // 黑色
        case 1: return Scalar(255, 255, 255); // 白色
        case 2: return Scalar(0, 0, 255);     // 红色
        case 3: return Scalar(255, 0, 0);     // 蓝色
        case 4: return Scalar(0, 255, 0);     // 绿色
        case 5: return Scalar(255, 0, 255);   // 紫色
        case 6: return Scalar(0, 255, 255);   // 黄色
        case 7: return Scalar(255, 255, 0);   // 青色
        default: return Scalar(0, 0, 0);      // 默认黑色
    }
}

// 题目（2）的解码函数：将颜色转换为八进制位
int decodeOctal(Scalar color) {
    // 比较颜色值
    if (color == Scalar(0, 0, 0)) return 0;
    if (color == Scalar(255, 255, 255)) return 1;
    if (color == Scalar(0, 0, 255)) return 2;
    if (color == Scalar(255, 0, 0)) return 3;
    if (color == Scalar(0, 255, 0)) return 4;
    if (color == Scalar(255, 0, 255)) return 5;
    if (color == Scalar(0, 255, 255)) return 6;
    if (color == Scalar(255, 255, 0)) return 7;
    return -1; // 未知颜色
}

// 统一的发送接口
void send(int msg, bool isBinary = true) {
    Mat img(100, 100, CV_8UC3, isBinary ? encodeBinary(msg) : encodeOctal(msg));
    imshow("Sender", img);
    waitKey(1000); // 显示1秒
    destroyWindow("Sender");
}

// 统一的接收接口
int receive(bool isBinary = true) {
    VideoCapture cap(0);
    if (!cap.isOpened()) {
        cerr << "Error: Could not open camera." << endl;
        return -1;
    }

    Mat frame;
    cap >> frame;
    cap.release();

    Scalar color = frame.at<Vec3b>(frame.rows / 2, frame.cols / 2);
    return isBinary ? decodeBinary(color) : decodeOctal(color);
}

int main() {
    // 测试题目（1）
    cout << "Testing Binary Encoding/Decoding..." << endl;
    send(1, true); // 发送比特1
    int received_bit = receive(true);
    cout << "Received Bit: " << received_bit << endl;

    // 测试题目（2）
    cout << "Testing Octal Encoding/Decoding..." << endl;
    send(3, false); // 发送八进制位3
    int received_octal = receive(false);
    cout << "Received Octal: " << received_octal << endl;

    return 0;
}